package com.atguigu.lock;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessLock;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

/**
 * className: CuratorLockTest
 * description:
 * date: 2024/6/21-18:34
 * <p>
 * project: zookeeper
 * package: com.atguigu.lock
 * email: 1085844536@qq.com
 * version:
 *
 * @author WangGuojian
 */
public class CuratorLockTest {

    private String rootNode = "/locks";
    /**
     * zookeeper server 列表
     */
    private static final String CONNECT_STRING = "192.168.33.100:2181,192.168.33.101:2181,192.168.33.102:2181";

    /**
     * connection 超时时间
     */
    private static final int CONNECTION_TIMEOUT = 2000;
    /**
     * session 超时时间
     */
    private static final int SESSION_TIMEOUT = 2000;

    public static void main(String[] args) {
        new CuratorLockTest().test();
    }

    /**
     * 测试
     */
    private void test() {
        // 创建分布式锁 1
        final InterProcessLock lock1 = new InterProcessMutex(getCuratorFramework(), rootNode);
        // 创建分布式锁 2
        final InterProcessLock lock2 = new InterProcessMutex(getCuratorFramework(), rootNode);
        new Thread(() -> {
            // 获取锁对象
            try {
                lock1.acquire();
                System.out.println("线程 1 获取锁");
                // 测试锁重入
                lock1.acquire();
                System.out.println("线程 1 再次获取锁");
                Thread.sleep(5 * 1000);
                lock1.release();
                System.out.println("线程 1 释放锁");
                lock1.release();
                System.out.println("线程 1 再次释放锁");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(() -> {
            // 获取锁对象
            try {
                lock2.acquire();
                System.out.println("线程 2 获取锁");
                // 测试锁重入
                lock2.acquire();
                System.out.println("线程 2 再次获取锁");
                Thread.sleep(5 * 1000);
                lock2.release();
                System.out.println("线程 2 释放锁");
                lock2.release();
                System.out.println("线程 2 再次释放锁");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * 分布式锁初始化
     */
    public CuratorFramework getCuratorFramework() {
        // 重试策略，初试时间 3 秒，重试 3 次
        RetryPolicy policy = new ExponentialBackoffRetry(3000, 3);
        // 通过工厂创建 Curator
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(CONNECT_STRING)
                .connectionTimeoutMs(CONNECTION_TIMEOUT)
                .sessionTimeoutMs(SESSION_TIMEOUT)
                .retryPolicy(policy).build();
        // 开启连接
        client.start();
        System.out.println("zookeeper 初始化完成...");
        return client;
    }
}
